package com.zkrt.upms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zkrt.upms.dto.DeviceDTO;
import com.zkrt.upms.dto.InfluxDto;
import com.zkrt.upms.entity.*;
import com.zkrt.upms.mapper.DeviceAttrRMapper;
import com.zkrt.upms.mapper.DeviceBMapper;
import com.zkrt.upms.service.IDeviceBService;
import com.zkrt.upms.service.InfluxdbService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Slf4j
@Service
public class DeviceBServiceImpl implements IDeviceBService {

    @Autowired
    private DeviceBMapper deviceMapper;

    @Autowired
    private DeviceAttrRMapper attrMapper;

    @Autowired
    private InfluxdbService influxdbService;

    /**
     * 配置单个设备
     * @param device
     * @return
     */
    private int config(final DeviceB device) {
        if (device != null) {

            DeviceB deviceB = new DeviceB();
            BeanUtil.copyProperties(device, deviceB);
            deviceB.setId(UUID.randomUUID().toString());
            int ident = deviceMapper.insert(deviceB);

            if (ident > 0) {
                return ident;
            }
        }
        return 0;
    }

    /**
     * 查询设备（分页）
     * @param sn
     * @param name
     * @param current
     * @param size
     * @return
     */
    @Override
    public R page(final String sn, final String name, final Boolean disabled, Long current, Long size) {
        if (current == null) {
            current = 1l;
        }
        if (size == null) {
            size = 10l;
        }
        IPage<DeviceB> page = new Page<>(current, size);
        LambdaQueryWrapper<DeviceB> deviceWrapper = new LambdaQueryWrapper<>();
        if (sn != null) {
            deviceWrapper.eq(DeviceB::getSn, sn);
        }
        if (name != null) {
            deviceWrapper.like(DeviceB::getName, name);
        }
        if (disabled != null) {
            deviceWrapper.eq(DeviceB::getDisabled, disabled);
        }
        page = deviceMapper.selectPage(page, deviceWrapper);
        List<DeviceB> devices = page.getRecords();
        List<DeviceDTO> dtos = devices.stream().map(d -> {
            DeviceDTO dto = new DeviceDTO();
            BeanUtil.copyProperties(d, dto);
            LambdaQueryWrapper<DeviceAttrR> attrWrapper = new LambdaQueryWrapper<>();
            attrWrapper.eq(DeviceAttrR::getSn, d.getSn());
            List<DeviceAttrR> attrs = attrMapper.selectList(attrWrapper);
            dto.setAttrs(attrs);
            return dto;
        }).collect(Collectors.toList());
        IPage dtoPage = new Page<DeviceDTO>(current, size, page.getTotal());
        dtoPage.setRecords(dtos);
        return R.ok(dtoPage);
    }

    /**
     * 配置设备信息
     * @param devices
     * @return
     */
    @Override
    public R config(final List<DeviceB> devices) {
        if (devices != null) {
            for(DeviceB device : devices) {
                if (!ObjectUtil.isNotEmpty(device.getSn())) { // sn为空
                    return R.failed("sn不能为空");
                }
                if (!ObjectUtil.isNotEmpty(device.getGwCode())) { // gwCode为空
                    return R.failed("gwCode不能为空");
                }
                if (!ObjectUtil.isNotEmpty(device.getUniqueId())) { // uniqueId为空
                    return R.failed("uniqueId不能为空");
                }
            }
            AtomicInteger count = new AtomicInteger();

            for (DeviceB d : devices) {
                LambdaQueryWrapper<DeviceB> deviceWrapper = new LambdaQueryWrapper<>();
                deviceWrapper.eq(DeviceB::getSn, d.getSn());
                deviceWrapper.eq(DeviceB::getUniqueId,d.getUniqueId());

               /* Integer size = deviceMapper.selectCount(deviceWrapper);

                if (size>0){
                    return R.failed("此设备已存在");
                }*/

                int ident = config(d);
                count.addAndGet(ident);
            }

            if (devices.size() == count.get()) {
                return R.ok(devices);
            }
        }
        return R.failed("缺少参数");
    }

    /**
     * 删除设备
     * @param ids
     * @return
     */
    @Override
    public R delete(final List<String> ids) {
        if (ids == null || ids.size() == 0) {
            return R.failed("ids不能为空");
        }
        LambdaQueryWrapper<DeviceB> deviceWrapper = new LambdaQueryWrapper<>();
        deviceWrapper.in(DeviceB::getId, ids);
        List<DeviceB> devices = deviceMapper.selectList(deviceWrapper);
        if (devices != null && devices.size() > 0) {
            List<String> idList = devices.stream().map(d -> d.getId()).collect(Collectors.toList());
            int ident = deviceMapper.deleteBatchIds(idList);
            if (ident > 0) {
                return R.ok(devices);
            }
            return R.failed("删除失败");
        } else {
            return R.failed("无删除设备");
        }
    }

    @Override
    public R getAll() {
        List<DeviceB> deviceBS = deviceMapper.selectList(new LambdaQueryWrapper<>());
        return R.ok(deviceBS);
    }

    @Override
    public R getAllAttr() {
        List<DeviceAttrR> attrRList = attrMapper.selectList(new LambdaQueryWrapper<>());

        return R.ok(attrRList);
    }

    @Override
    public String getScript(String day) {

        Date start=new Date();
        Date end=new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        try {
            // 解析日期字符串
            Date date = sdf.parse(day);

            // 创建Calendar实例并设置日期
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);

            // 获取前一天00:00:00
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);

            start=calendar.getTime();

            // 获取23:59:59.999的时间戳
            calendar.set(Calendar.HOUR_OF_DAY, 23);
            calendar.set(Calendar.MINUTE, 59);
            calendar.set(Calendar.SECOND, 59);
            calendar.getTime();
            end=calendar.getTime();

        } catch (ParseException e) {
            e.printStackTrace();
        }

        log.info("开始时间:"+start);

        log.info("结束时间:"+end);

        ArrayList<String> list = new ArrayList<>();

        HashMap<String,Map<String,String>> buckets = new HashMap<>();

        YLJJpConfig jpConfig = new YLJJpConfig();
        YLJLhkConfig lhkConfig = new YLJLhkConfig();
        YLJTzlConfig tzlConfig = new YLJTzlConfig();
        YLJYfgConfig yfgConfig = new YLJYfgConfig();

        HashMap<String,String> jp = new HashMap<>();
        jp.put("w01010",jpConfig.getW01010());
        jp.put("w01009",jpConfig.getW01009());
        jp.put("w01001",jpConfig.getW01001());

        HashMap<String,String> lhk = new HashMap<>();
        lhk.put("w01010",lhkConfig.getW01010());
        lhk.put("w01009",lhkConfig.getW01009());
        lhk.put("w01001",lhkConfig.getW01001());
        HashMap<String,String> tzl = new HashMap<>();
        tzl.put("w01010",tzlConfig.getW01010());
        tzl.put("w01009",tzlConfig.getW01009());
        tzl.put("w01001",tzlConfig.getW01001());
        HashMap<String,String> yfg = new HashMap<>();
        yfg.put("w01010",yfgConfig.getW01010());
        yfg.put("w01009",yfgConfig.getW01009());
        yfg.put("w01001",yfgConfig.getW01001());

        buckets.put(jpConfig.getBucket(),jp);
        buckets.put(lhkConfig.getBucket(), lhk);
        buckets.put(tzlConfig.getBucket(),tzl);
        buckets.put(yfgConfig.getBucket(),yfg);

        HashMap<String, Map<String,Map<String,AttributeData>>> toto = new HashMap<>();

        for (String s : buckets.keySet()) {

            Map<String, String> map = buckets.get(s);

            Map<String,Map<String,AttributeData>> goToMap = new HashMap<>();

            for (String m : map.keySet()) {

                InfluxDto influxDto = new InfluxDto();
                influxDto.setDevSn(map.get(m));
                influxDto.setFields(Arrays.asList(m));
                Map<String, List<AttributeData>> histories = influxdbService.getHistories(s, influxDto, start, end);

                Map<String,AttributeData> dataMap=new HashMap<>();

                histories.keySet().forEach(h->{

                    List<AttributeData> attributeData = histories.get(h);

                    for (int i = 0; i < attributeData.size(); i++) {
                        String theTime = attributeData.get(i).getTheTime();

                        DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
                        LocalDateTime dateTime = LocalDateTime.parse(theTime, formatter);
                        int hour = dateTime.getHour();
                        dataMap.put(String.valueOf(hour),attributeData.get(i));
                    }
                });

                goToMap.put(m,dataMap);
            }
            toto.put(s,goToMap);

        }

        HashMap<String, String> mnMap = new HashMap<>();
        mnMap.put(jpConfig.getBucket(), jpConfig.getMn());
        mnMap.put(lhkConfig.getBucket(), lhkConfig.getMn());
        mnMap.put(tzlConfig.getBucket(),tzlConfig.getMn());
        mnMap.put(yfgConfig.getBucket(),yfgConfig.getMn());

        HashMap<String, String> stMap = new HashMap<>();
        stMap.put(jpConfig.getBucket(), jpConfig.getSt());
        stMap.put(lhkConfig.getBucket(), lhkConfig.getSt());
        stMap.put(tzlConfig.getBucket(),tzlConfig.getSt());
        stMap.put(yfgConfig.getBucket(),yfgConfig.getSt());

        for (String s : toto.keySet()) {
            for (int i = 0; i < 24; i++) {

                AttributeData w01009 = toto.get(s).get("w01009").get(Integer.toString(i));
                AttributeData w01010 = toto.get(s).get("w01010").get(Integer.toString(i));
                AttributeData w01001 = toto.get(s).get("w01001").get(Integer.toString(i));

                if (w01009!=null||w01010!=null||w01001!=null){

                    StringBuffer buffer = new StringBuffer("curl -iv -X POST -H \"Content-Type: application/json\" -d  '{\"pushTime\": \"");

                    buffer.append(day+String.format("%02d", i)+"0000");
                    buffer.append("\",\"mn\": \"");
                    buffer.append(mnMap.get(s));
                    buffer.append("\",\"st\": \"");
                    buffer.append(stMap.get(s));
                    buffer.append("\",\"attrs\": [{\"attrKey\": \"w01009\",\"value\": \"");

                    buffer.append(w01009.getValue());
                    buffer.append("\"},{\"attrKey\": \"w01010\",\"value\": \"");
                    buffer.append(w01010.getValue());
                    buffer.append("\"},{\"attrKey\": \"w01001\",\"value\": \"");
                    buffer.append(w01001.getValue());
                    buffer.append("\"}]}'  http://10.185.245.51:32037/api/data/upload/toData");


                    list.add(buffer.toString());
                }

            }
        }

        if (list!=null&&list.size()>0){
            StringBuffer re=new StringBuffer(list.get(0));

            for (int i = 1; i < list.size(); i++) {
                re.append("\n");
                re.append("sleep 20");
                re.append("\n");
                re.append(list.get(i));

            }
            return re.toString();
        }else {
            return "";
        }

    }

}
